import {
    run,
    queryAll,
    queryOne,
    queryCount,
    insert,
    insertOrReplace,
    insertOrIgnore,
    update
} from '../ADB'

/* 枚举类型转数字，和服务端对应 */
const enum2Int = (enumStr) => {
    switch (enumStr) {
        // contactType
        case "USER": return 0
        case "GROUP": return 1

        // messageType
        case "TEXT": return 0
        case "MEDIA": return 1
        case "NOTICE": return 2

        // fileType
        case "IMAGE": return 0
        case "VIDEO": return 1
        case "OTHER": return 2

        // sendStatus
        case "SENDING": return 0
        case "SENT": return 1
        default: return enumStr
    }
}

// userId从store中获取
import store from '../../store'
import { increaseNoReadCount } from './ChatSessionUserModel'


const getPageQuery = (pageNo, pageSize, totalCount) => {
    // 获取总页数，js除法得到小数，所以非整除时取整后+1
    const pageTotal = totalCount % pageSize == 0 ? totalCount / pageSize : Number.parseInt(totalCount / pageSize + 1)
    // 合法的页码范围
    pageNo = pageNo < 1 ? 1 : pageNo
    pageNo = pageNo > pageTotal ? pageTotal : pageNo
    return {
        pageTotal,
        offset: (pageNo - 1) * pageSize,
        limit: pageSize
    }
}

const getChatMessageList = async (sessionId, pageNo, maxMessageId) => {
    // 分页查询，需要先查询总记录数
    const totalCount = await queryCount("select count(*) from chat_message where session_id = ? and user_id = ?", [sessionId, store.getUserId()])
    // 根据pageNo和pageSize计算limit和offset，这里pageSize定为20
    const { pageTotal, offset, limit } = getPageQuery(pageNo, 20, totalCount)
    const params = [sessionId, store.getUserId()]
    // 如果maxMessageId存在，则添加条件
    if (maxMessageId) {
        params.push(maxMessageId)
    }
    params.push(offset)
    params.push(limit)
    const dataList = await queryAll("select * from chat_message where session_id = ? and user_id = ? " + (maxMessageId ? "and message_id <= ?" : "") + " order by message_id desc limit ?, ?", params)
    return {
        pageTotal,
        dataList
    }
}

const saveChatMessageList4Init = (chatMessageList) => {
    return new Promise(async (resolve, reject) => {
        try {
            // 统计未读消息数量
            const countMap = {}
            // 服务端返回的chatMessageList是距离自己上次离线后的消息记录
            // 查询的条件是所有contactId in (用户加入的群聊, 用户自己)，即所有发给 自己加入的群聊 和 自己 的消息
            // 这里要保存到本地数据库里，消息对客户端的用户来说
            // 如果contactType是群聊的话contactId就是群聊id
            // 如果是用户的话，因为是未读消息，所以消息肯定是别人发给自己的，所以contactId就是sendUserId
            chatMessageList.forEach(item => {
                let contactId = item.contactType == "USER" ? item.sendUserId : item.contactId
                if (!countMap[contactId]) {
                    countMap[contactId] = 1
                }
                else {
                    countMap[contactId] += 1
                }
            });
            // 更新未读消息数量，需要使用到chat_session_user表，使用导入的函数
            for (let contactId in countMap) {
                await increaseNoReadCount(contactId, countMap[contactId])
            }
            // 保存消息到数据库，所有保存操作是异步执行的
            let allAwaits = []
            chatMessageList.forEach(async item => {
                allAwaits.push(saveChatMessage(item))
            })
            // 等待所有消息保存完成后再resolve，这样后面的打印日志才不会乱（不然后面的日志会先打印）
            await Promise.all(allAwaits)
            resolve();
        } catch (e) {
            console.error("saveChatMessageList4Init error: " + e)
            resolve();  // 忽略错误
        }
    })
}

/* 保存聊天信息，注意：这个函数没有增加未读消息数量（所以直接调用时要确保是在发送消息，即就在当前窗口） */
const saveChatMessage = (item) => {
    item.userId = store.getUserId()
    // 把contactType、message_type、fileType、sendStatus的枚举转为数字
    item.contactType = enum2Int(item.contactType)
    item.messageType = enum2Int(item.messageType)
    item.fileType = enum2Int(item.fileType)
    item.sendStatus = enum2Int(item.sendStatus)
    return insertOrReplace("chat_message", item)
}

/* 更新消息 */
const updateChatMessage = (data, params) => {
    params.userId = store.getUserId()
    return update("chat_message", data, params)
}

/* 根据messageId获取消息 */
const getChatMessage = (messageId) => {
    return queryOne("select * from chat_message where message_id = ? and user_id = ?", [messageId, store.getUserId()])
}

export {
    saveChatMessageList4Init,
    getChatMessageList,
    saveChatMessage,
    updateChatMessage,
    getChatMessage
}
